﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Remoting;
using CookComputing.XmlRpc;
using sir_mix_csharp.entidades;


namespace sir_mix_csharp.rpc_xml
{
    /// <summary>
    /// Classe que é acionada quando o servidor deseja notificar o cliente sobre alguma situação.
    /// </summary>
    class ServicosCliente : MarshalByRefObject 
    {
        /// <summary>
        /// Método acionado quando é recebido notificação do servidor que este realizou uma transação utilizando um registro de compra do acionista.
        /// </summary>
        /// <param name="empresa">nome da empresa da ação que foi comprada.</param>
        /// <param name="tempoInicial">tempo de quando o registro de compra foi criado, utilizado para identificar unicamente cada registro.</param>
        /// <param name="qtdeAcoes">quantidade de ações compradas.</param>
        /// <param name="preco">preço que as ações foram compradas.</param>
        [XmlRpcMethod("notificarCompraEfetuada")]
        public int notitificarCompraEfetuada(string empresa, string tempoInicial, int quantidadeAcoes, double preco)
        {
            foreach (RegistroInteresse compra in UtilRPC.compras)
            {
                if (compra.getAcao().getEmpresa().Equals(empresa))
                {
                    if (compra.getTempoInicial().Equals(tempoInicial))
                    {
                        int novaQtde = compra.getAcao().getQuantidade() - quantidadeAcoes;
                        if (novaQtde == 0)
                        {
                            UtilRPC.compras.Remove(compra);
                        }
                        else
                        {
                            compra.getAcao().setQuantidade(novaQtde);
                        }
                        atualizarQtdeAcoes(empresa, quantidadeAcoes);
                        string mensagem = String.Format("Realizei a compra de {0} ações da empresa {1} por R${2}!", quantidadeAcoes.ToString(), empresa, preco.ToString());
                        UtilRPC.janelaPrincipal.inserirLog(mensagem);
                        return 1;
                    }
                }
            }
            return 0;
        }

        /// <summary>
        /// Método acionado quando é recebido notificação do servidor que este realizou uma transação utilizando um registro de venda do acionista.
        /// </summary>
        /// <param name="empresa">nome da empresa da ação.</param>
        /// <param name="tempoInicial">tempo de quando o registro foi criado, utilizado para identificar unicamente cada registro.</param>
        /// <param name="quantidadeAcoes">quantidade de ações vendidas.</param>
        /// <param name="preco">preço que as ações foram vendidas.</param>
        [XmlRpcMethod("notificarVendaEfetuada")]        
        public int notitificarVendaEfetuada(string empresa, string tempoInicial, int quantidadeAcoes, double preco)
        {
            foreach (RegistroInteresse venda in UtilRPC.vendas)
            {                
                if (venda.getAcao().getEmpresa().Equals(empresa))
                {
                    if (venda.getTempoInicial().Equals(tempoInicial))
                    {
                        int novaQtde = venda.getAcao().getQuantidade() - quantidadeAcoes;
                        if (novaQtde == 0)
                        {
                            UtilRPC.vendas.Remove(venda);
                        }
                        else
                        {
                            venda.getAcao().setQuantidade(novaQtde);
                        }
                        atualizarQtdeAcoes(empresa, 0 - quantidadeAcoes);
                        string mensagem = String.Format("Realizei a venda de {0} ações da empresa {1} por R${2}!", quantidadeAcoes.ToString(), empresa, preco.ToString());
                        UtilRPC.janelaPrincipal.inserirLog(mensagem);
                        return 1;
                    }
                }
            }
            return 0;
        }

        /// <summary>
        /// Método acionado quando é recebido notificação do servidor que um registro de compra expirou.
        /// </summary>
        /// <param name="empresa">nome da empresa da ação.</param>
        /// <param name="tempoInicial">tempo de quando o registro foi criado, utilizado para identificar unicamente cada registro.</param>
        [XmlRpcMethod("notificarCompraExpirada")]
        public int notitificarCompraExpirada(string empresa, string tempoInicial)
        {
            foreach (RegistroInteresse compra in UtilRPC.compras)
            {
                if (compra.getTempoInicial().Equals(tempoInicial))
                {
                    if (compra.getAcao().getEmpresa().Equals(empresa))
                    {
                        UtilRPC.compras.Remove(compra);
                        string mensagem = String.Format("O registro de compra de ações da empresa {0} expirou!", empresa);
                        UtilRPC.janelaPrincipal.inserirLog(mensagem);
                        return 1;
                    }
                }
            }
            return 0;
        }

        /// <summary>
        /// Método acionado quando é recebido notificação do servidor que um registro de venda expirou.
        /// </summary>
        /// <param name="empresa">nome da empresa da ação.</param>
        /// <param name="tempoInicial">tempo de quando o registro foi criado, utilizado para identificar unicamente cada registro.</param>
        [XmlRpcMethod("notificarVendaExpirada")]
        public int notitificarVendaExpirada(string empresa, string tempoInicial)
        {
            foreach (RegistroInteresse venda in UtilRPC.vendas) {
                if (venda.getTempoInicial().Equals(tempoInicial)) { 
                    if (venda.getAcao().getEmpresa().Equals(empresa)){
                        UtilRPC.vendas.Remove(venda);
                        string mensagem = String.Format("O registro de venda de ações da empresa {0} expirou!", empresa);
                        UtilRPC.janelaPrincipal.inserirLog(mensagem);
                        return 1;
                    }
                }
            }
            return 0;
        }

        /// <summary>
        /// Método utilizado para atualizar a quantidade de ações do acionista, baseado na quantidade de ações quem foram compradas ou vendidas. Caso o acionista não tenha mais ações de uma determinada empresa, o seu registro é excluído da lista de ações.
        /// </summary>
        /// <param name="empresa">nome da empresa da ação.</param>
        /// <param name="quantidade">quantidade de ações que foram transacionadas. Se for um número positivo, o acionista adquiriu novas ações de uma empresa, e se o número for negativo, o acionista vendeu ações de uma empresa.</param>
        internal void atualizarQtdeAcoes(string empresa, int quantidade)
        {
            bool achouAcao = false;
            foreach (Acao acao in UtilRPC.listaAcoes)
            {
                if (acao.getEmpresa().Equals(empresa))
                {
                    achouAcao = true;
                    int novaQtde = acao.getQuantidade() + quantidade;
                    if (novaQtde == 0)
                    {
                        UtilRPC.listaAcoes.Remove(acao);
                        return;
                    }
                    acao.setQuantidade(novaQtde);
                }
            }
            if (!achouAcao)
            {
                Acao acao = new Acao(empresa, quantidade);
                UtilRPC.listaAcoes.Add(acao);
            }
        }
    }
}
